package com.oneinlet.config;

import com.oneinlet.component.shiro.GuardAuthorizationFilter;
import com.oneinlet.component.shiro.GuardAuthorizingRealm;
import com.oneinlet.component.shiro.RedisSessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by WangZiHe on 2018/6/8
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */
@Configuration
public class ShiroConfig {

    private Map<String, Filter> filtersMap = new LinkedHashMap<>();

    private Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();


    @Bean
    public GuardAuthorizingRealm myRealm() {
        return new GuardAuthorizingRealm();
    }

    @Bean
    public GuardAuthorizationFilter getFilter() {
        return new GuardAuthorizationFilter();
    }

    @Bean
    public RedisSessionManager getSessionManager() {
        return new RedisSessionManager();
    }

    @Bean
    public SimpleCookie getSessionCookie() {
        SimpleCookie cookie = new SimpleCookie("yc");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(-1);
        return cookie;
    }

    @Bean
    public SimpleCookie getRememberMeCookie() {
        SimpleCookie cookie = new SimpleCookie("remember");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(86400 * 5);
        return cookie;
    }

    @Bean
    public CookieRememberMeManager getCookieRememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(getRememberMeCookie());
        return cookieRememberMeManager;
    }

    @Bean
    public DefaultWebSessionManager getDefaultWebSessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        defaultWebSessionManager.setSessionIdCookie(getSessionCookie());
        return defaultWebSessionManager;
    }

    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager defaultWebSessionManager = new DefaultWebSecurityManager();
        defaultWebSessionManager.setSessionManager(getDefaultWebSessionManager());
        defaultWebSessionManager.setRememberMeManager(getCookieRememberMeManager());
        defaultWebSessionManager.setRealm(myRealm());
        return defaultWebSessionManager;
    }

    @Bean
    public MethodInvokingFactoryBean getMethodInvokingFactoryBean() {
        MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
        methodInvokingFactoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
        methodInvokingFactoryBean.setArguments(getDefaultWebSecurityManager());
        return methodInvokingFactoryBean;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(getDefaultWebSecurityManager());
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());

        filtersMap.put("authRole", getFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);


        filterChainDefinitionMap.put("/user/save", "authRole");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

}
